/**************************************************************************
 * @doc ACCUM
 * @module ACCUM.C - Source code for the accumulator handling functions.|
 * Source code for the accumulator handling functions.
 *
 * Product     :   SoftPay 2000 (Global Payment Methodology).
 * <nl>Developer   :   SoftPay Development Team (I_SP2000).
 * <nl>Notes       :
 *
 * @head3 ACCUM Functions |
 * @index | ACCUM
 * @end
 *
 * Copyright (c) 1996-2000 by VeriFone Inc. All rights reserved.
 *
 * No part of this software may be used, stored, compiled, reproduced,
 * modified, transcribed, translated, transmitted, or transferred, in any form
 * or by any means whether electronic, mechanical, magnetic, optical,
 * or otherwise, without the express prior written permission of VeriFone, Inc.
 *
 * Revision History
 * ------------------------------------------------------------------------
$Log:  $
 * ------------------------------------------------------------------------
 ********************************************************************************/
#ifdef IMAM_LOG
#ifndef LOGSYS_FLAG
#define LOGSYS_FLAG
#endif
#endif

#include <project.h>

#ifdef ACCUM_DEFINED

#define ACCUM_C

#include <stdlib.h>
#include <aclstr.h>
#include <ctype.h>
#include <errno.h>
#include <SVC.H>
#include <stdio.h>
#include <message.h>
#include <iso8583.h>
#include <amexhost.h>
#include <applidl.h>                    /* For KEY_CANCEL definition */
#include <formater.h>
#include <string.h>
#include <actutil.h>
#include <varrec.h>
///** /#define DEBUG_ACCUM  /**/
#ifdef DEBUG_ACCUM
#define DEBUG_95
#endif

#include <define.h>
#include <tranSACT.h>
#include <table.h>
#include <tran.h>
#include <gds.h>
#include <tblutil.h>
#include <confio.h>
#include <format.h>
#include <funcids.h>
#include <mdlfuncs.h>
#include <merch.h>
#include <msg.h>
#include <msgfuncs.h>
#include <pbatch.h>
#include <trt.h>
#include <form.h>
#include <print.h>
#include <ui.h>
#include <util.h>
#include <date.h>
#include <spdebug.h>
#include <pfr.h>
#include <accum.h>
#include <accmsg.h>
#include <codesec.h>
#include <confproto.h>
#include <iit.h>


FUNCTION_TABLE srAccumFuncs[] = {
    {inUpdateAccumFlow,                 UPDATE_ACCUM},
    {inSummaryReportOperation,          PRINT_SUMMARY_REPORT},
    {inBatchTotalsOperation,            BATCH_TOTALS_OP_FUNC},
    {inDefaultUpdateAccumValues,        UPDATE_ACCUM_VALUES},
    {inDefaultVoidUpdateAccumValues,    UPDATE_VOID_ACCUM_VALUES},
    {0,                             END_OF_FUNC_TABLE},

};

/*********************************************************************************************
* @func int | inAddAccumFunctions |
*       Adds ACCUM functions to the flexi record.
*
* @rdesc return values.
* @flag int    |  VS_ERR, VS_ESCAPE or VS_SUCCESS
* @end
**********************************************************************************************/

int inAddAccumFunctions() {
    int inCount = 0;

    /* Add ACCUM functions to the flexi record */
    do {
        if (inAddFunctionPointer(srAccumFuncs[inCount].inFieldID, srAccumFuncs[inCount].pinFunction) == VS_ERR)
            return (VS_ERR);
        inCount++;
    } while (srAccumFuncs[inCount].inFieldID != END_OF_FUNC_TABLE);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func void | vdGetASIFName |
* Gets the name for the ASI file.
*
* @parm char * | pchFName |
*        ASI file name.
* @end
**********************************************************************************************/

void vdGetASIFName(char* pchFName) {
    sprintf(pchFName, "ASI%02d%02d.DAT", inGetBatchIndex(), inGetMerchantNum());

    ///** /pdebug(("pchFName = %s", pchFName));/**/
}

/*********************************************************************************************
* @func int | inSetASIFile |
* Sets the flag for the Issuer in the ASI file.
*
*
* @parm int | inIssuer |
*       This is the issuer flag value.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inSetASIFile(int inIssuer) {
    int inResult;
    FHANDLE hFHandle;
    ACCUM_SHIFT srASI;
    char szFileName[FILENAME_SIZE + 1];

    vdGetASIFName(szFileName);
    hFHandle = open(szFileName, O_RDWR);
    if (hFHandle < 0) {
        if ((hFHandle = open(szFileName, O_CREAT | O_RDWR)) < 0)
            return(VS_ERR);

        memset((char *) &srASI, 0x00, SIZE_ACCUM_SHIFT);
    } else
        inResult = read(hFHandle, (char *) &srASI, SIZE_ACCUM_SHIFT);

    if (srASI.srIssuer.fActiveAccum[inIssuer] != '1') {
        srASI.srIssuer.fActiveAccum[inIssuer] = '1';

        lseek(hFHandle, 0l, SEEK_SET);
        inResult = write(hFHandle, (char *) &srASI, SIZE_ACCUM_SHIFT);

        if (inResult != (int) SIZE_ACCUM_SHIFT)              /* Error writing record info */ {
            close(hFHandle);
            return(VS_ERR);
        }
    }
    close(hFHandle);
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inResetASIFile |
* Resets the flags in the ASI file.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inResetASIFile() {
    int inResult;
    FHANDLE hFHandle;
    ACCUM_SHIFT srASI;
    char szFileName[FILENAME_SIZE + 1];

    vdGetASIFName(szFileName);
    hFHandle = open(szFileName, O_RDWR);
    if (hFHandle < 0) {
        if ((hFHandle = open(szFileName, O_CREAT | O_RDWR)) < 0)
            return(VS_ERR);
    }
    memset((char *) &srASI, 0x00, SIZE_ACCUM_SHIFT);

    inResult = write(hFHandle, (char *) &srASI, SIZE_ACCUM_SHIFT);
    if (inResult != (int) SIZE_ACCUM_SHIFT)              /* Error writing record info */ {
        close(hFHandle);
        return(VS_ERR);
    }
    close(hFHandle);
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func void | vdGetAccumFName |
* Gets accumulator file name.
*
* @parm char * | pchFName |
*       Pointer to accumulator filename.
*
* @rdesc VOID
* @end
**********************************************************************************************/
void vdGetAccumFName(char* pchFName) {
    ///** /pdebug(("--vdGetAccumFName--"));/**/

    /* sprintf(pchFName, "ACC%02d", inGetHDTBatchIndex()); */

    /* create accums based on host and merchant */
    sprintf(pchFName, "ACC%02d%02d", inGetBatchIndex(), inGetMerchantNum());

    /** /pdebug(("pchFName = %s", pchFName));*/
}

/*********************************************************************************************
* @func int | inOpenAccum |
* Opens/Creates the desired Accum batch file..
*
* @parm DB_FILE * | psrDBFPtr |
*       Pointer to accumulator database file.
*
* @parm char * | pchFName |
*       Accumulator Database file name.The filename MUST NOT contain a file extension.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inOpenAccum(DB_FILE* psrDBFPtr,char* pchFName) {
    int inRetVal;

    /** /pdebug(("--inOpenAccum--"));*/

    inRetVal = db_open(psrDBFPtr, pchFName, SIZE_ACCUM_KEY, O_RDWR);

    if (inRetVal < 0) /* If file is non-existant, create it */
        //mb1   if (errno == ENOENT)
        inRetVal = db_open(psrDBFPtr, pchFName, SIZE_ACCUM_KEY, (O_CREAT | O_RDWR));

    if (inRetVal < 0)
        return(VS_ERR);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inCloseAccum |
* Closes the desired Accum batch file.
*
* @parm DB_FILE * | psrDBFPtr |
*       Pointer to accumulator database file.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inCloseAccum(DB_FILE* psrDBFPtr) {
    /** /pdebug(("--inCloseAccum--"));*/

    if (db_close(psrDBFPtr) > 0)
        return(VS_SUCCESS);

    return(VS_ERR);
}

/*********************************************************************************************
* @func int | inAccumCompFn |
*       This function will be called by the inKeyReadAccum function, as
*       one of the parameters of the db_get_key() function.
*
* @parm ACCUM_KEY * | psrKey |
*       Pointer to accumulator Key structure.
*
* @parm int | font_type |
*       This is the screen size to be set - FONT6X8, FONT8X10, FONT8X16, FONT16X16, FONT16X32.
*
* @rdesc Returns the size of the packet built.
* @flag int | 0
* @flag int | -1
**********************************************************************************************/
int inAccumCompFn(ACCUM_KEY* psrKey,ACCUM_SKEY* MatchKey) {
    int inRetVal;

    /** /pdebug(("--inAccumCompFn--"));*/

    inRetVal = -1;
    if (MatchKey->accumKey.inIssuerNumber == psrKey->inIssuerNumber)
        inRetVal = 0;

    /** /pdebug(("inRetVal = %d",inRetVal));*/
    return(inRetVal);
}

/*********************************************************************************************
* @func int | inKeyReadAccum |
* Before Calling this function ensure the following:
*    1. Fill the srBatchKey struct with relevant values
*    2. Set the global 'inSearchIndex' variable to the search field index.
*
*   @parm DB_FILE *| psrDBFPtr |
*         Pointer to accumulator database file
*
*   @parm ACCUM_REC * |psrRec |
*         Pointer to accumulator Record structure
*
*   @parm ACCUM_KEY * |psrKey |
*         Pointer to accumulator Key structure
*
*   @parm int | inKeyIdx |
*         Key index
*
*   @parm long * | plnRecNum |
*         Pointer to record number
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @flag int | VS_ESCAPE
* @end
**********************************************************************************************/
int inKeyReadAccum(DB_FILE* psrDBFPtr,ACCUM_REC* psrRec,ACCUM_KEY* psrKey,ACCUM_SKEY* psrAccumSKey,long* plnRecNum) {
    long lnRetVal;
    long lnDBWhat = DB_FIRST;

    /** /pdebug(("--inKeyReadAccum--"));*/

    lnRetVal = db_get_key(psrDBFPtr, psrKey, psrAccumSKey, lnDBWhat, (char *) psrRec, SIZE_ACCUM_REC, plnRecNum);

    if (lnRetVal == 0L) {
        memset(psrRec, '\0', SIZE_ACCUM_REC);
        return (VS_ERR);
    } else if (lnRetVal == -1L)
        return (VS_ESCAPE);
    return (VS_SUCCESS);
}


/*********************************************************************************************
* @func int | inSetAccum |
* If the first time, it creates the accumulator file,
* initializes all the variables and writes back updated data.
* Else it reads the old data and updates the values and write back.
*
* @parm TRANSACTION_OBJECT * |pobTran |
*       Transaction object.
*
* @parm int | inAccumType |
*       Type of accumulator.
*
* @parm ACCUM_VALUES | srAccum |
*       The accumlator values.
*
* @parm int | inTotalType |
*       Type of totals.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inSetAccum(TRANSACTION_OBJECT* pobTran,int inAccumType,ACCUM_VALUES srAccum,int inTotalType) {
    char szFileName[FILENAME_SIZE + 1];
    DB_FILE srDBFPtr;
    ACCUM_REC srAccumRec;
    ACCUM_KEY srAccumKey;
    ACCUM_SKEY srAccumSKey;
    int inKeyIdx = 0;
    long lnRecNum = 0L;
    int inRetVal;

    /** /pdebug(("--inSetAccum--"));*/

    if ((inTotalType < 0) || (inTotalType >= MAX_TOTAL_SETS)) {
        vdSGErrorMessage(ACCUM_ERR_MSG);
        return(VS_ERR);
    }
    if ((inAccumType < 0) || (inAccumType >= MAX_ACCUM_TYPES)) {
        vdSGErrorMessage(ACCUM_ERR_MSG);
        return(VS_ERR);
    }
    /** /pdebug(("Total Type=%d",inTotalType));*/
    /** /pdebug(("Accum Type=%d",inAccumType));*/
    /** /pdebug(("Count=%d",srAccum.inCount));*/
    /** /pdebug(("Amount=%d",srAccum.lnTotal));*/

    srAccumSKey.compare_func = inAccumCompFn;

	if (fGetImamReportPerCard()){
		LOG_PRINTFF((0x08L, "ACCUM PER CARD = [%d]",inGetImamCDTIndex()));
		srAccumSKey.accumKey.inIssuerNumber = inGetImamCDTIndex(); 
	} else {
		LOG_PRINTFF((0x08L, "ACCUM PER ISSUER = [%d]",inGetIssuerNum()));
		srAccumSKey.accumKey.inIssuerNumber = inGetIssuerNum();
	}

    vdGetAccumFName(szFileName);

    if (inOpenAccum(&srDBFPtr, szFileName) != VS_SUCCESS) {

        vdSGErrorMessage(BATCH_ERR_MSG);
        return(VS_ERR);
    }

    /* If record does not exist then append new record */
    inRetVal = inKeyReadAccum(&srDBFPtr, &srAccumRec, &srAccumKey, &srAccumSKey, &lnRecNum);

    if (inRetVal == VS_ERR) {
        lnRecNum = DB_APPEND;
		if (fGetImamReportPerCard()){
			srAccumKey.inIssuerNumber = inGetImamCDTIndex(); 
		} else {
			srAccumKey.inIssuerNumber = inGetIssuerNum();
		}
    } else if (inRetVal == VS_ESCAPE) {
        inCloseAccum(&srDBFPtr);
        return (VS_ERR);
    }

    srAccumRec.srTotals[inTotalType].lnCount[inAccumType] += (long) srAccum.inCount;
    srAccumRec.srTotals[inTotalType].lnTipCount[inAccumType] += (long) srAccum.inTipCount;
    srAccumRec.srTotals[inTotalType].dbAmount[inAccumType] += srAccum.dbTotal;
    srAccumRec.srTotals[inTotalType].dbTip[inAccumType] += srAccum.dbTip;
    srAccumRec.srTotals[inTotalType].dbTax[inAccumType] += srAccum.dbTax;
    srAccumRec.srTotals[inTotalType].dbCashBack[inAccumType] += srAccum.dbCashBack;
    srAccumRec.srTotals[inTotalType].dbSurCharge[inAccumType] += srAccum.dbSurCharge;
    srAccumRec.srTotals[inTotalType].dbCustom1[inAccumType] += srAccum.dbCustom1;
    srAccumRec.srTotals[inTotalType].dbCustom2[inAccumType] += srAccum.dbCustom2;
#ifdef CITI_SING
    srAccumRec.srTotals[inTotalType].dbCustom3[inAccumType] += srAccum.dbCustom3;
    srAccumRec.srTotals[inTotalType].dbCustom4[inAccumType] += srAccum.dbCustom4;
#endif

    //meca 20041023 -- fixed from cashcard O3750 -- to correct the problem for totals report -- start
	#ifdef CASHCARD_DEFINED
	    srAccumRec.srTotals[inTotalType].lnSaleCnt[inAccumType] += (long)srAccum.inSaleCount;
	    srAccumRec.srTotals[inTotalType].lnCashOutCnt[inAccumType] += (long)srAccum.inCashOutCount;
	    srAccumRec.srTotals[inTotalType].lnSurChargeCnt[inAccumType] += (long)srAccum.inSurChrgCount;
	#endif //CASHCARD_DEFINED
    //meca 20041023 -- fixed from cashcard O3750 -- to correct the problem for totals report -- start

    /* Save the information */

    if (db_write(&srDBFPtr, &srAccumKey, (char *) &srAccumRec, SIZE_ACCUM_REC, lnRecNum) < 0) {

        vdSGErrorMessage(BATCH_ERR_MSG);
        inCloseAccum(&srDBFPtr);
        return(VS_ERR);
    }

    /* Set ASI file bit to allow totals report to do limited key reads  */

    inSetASIFile(srAccumSKey.accumKey.inIssuerNumber);

    inCloseAccum(&srDBFPtr);
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inUpdateAccum |
* Updates the accumulator based on the current transaction and host.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction object.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/

typedef int (*PFI_TO_AV)(TRANSACTION_OBJECT*,ACCUM_VALUES*);

int inUpdateAccum(TRANSACTION_OBJECT* pobTran) {
    ACCUM_VALUES srAccum;
    int inTranCardType;
    int inType,
    inVoidType;
    PFI_TO_AV pinTempFn;

    /** /pdebug(("--inUpdateAccum--"));*/

    memset(&srAccum, 0, (unsigned int)sizeof(ACCUM_VALUES));

    inType = pobTran->srBRec.inType;
    if (inType == ADJUST_CREDIT_TRAN)
        inType = CREDIT_TRAN;
    if (inType == ADJUST_DEBIT_TRAN)
        inType = DEBIT_TRAN;

    inTranCardType = pobTran->srBRec.inTranCardType;
    if (inTranCardType == PURCHASE_CARD || inTranCardType == EBT_CARD || inTranCardType == LOYALTY_CARD || inTranCardType == LOYCREDIT_CARD || inTranCardType == FLEET_CARD)
        inTranCardType = CREDIT_CARD;

    if (pobTran->srBKey.fVoided) {
        if (inType == CREDIT_TRAN)
            inVoidType = VOID_REFUND_TRAN;
        if (inType == DEBIT_TRAN)
            inVoidType = VOID_SALE_TRAN;

        #ifdef CASHCARD_DEFINED		//meca 20041023 -- fixed from cashcard O3750 -- to correct problem in totals report -- start

		        /* Put the values once for VOID bucket */
		        srAccum.inCount = 1;
		        if ( pobTran->srBRec.lnTipAmount > 0L )
			        srAccum.inTipCount = 1;
		        srAccum.dbTotal = (double) pobTran->srBKey.lnTotalOfTransactionAmount;
		        srAccum.dbTip = (double) pobTran->srBRec.lnTipAmount;
		        srAccum.dbTax = (double) pobTran->srBRec.lnTaxAmount;
		        srAccum.dbCashBack = (double) pobTran->srBRec.lnCashBackAmount;

			if ( (pinTempFn = inGetFunctionPointer(UPDATE_VOID_ACCUM_VALUES)) != NULL_PFI )
				pinTempFn(pobTran, &srAccum);

		        if(inSetAccum(pobTran, inVoidType, srAccum ,inTranCardType) != VS_SUCCESS)
		            return(VS_ERR);

		        srAccum.inCount = -1;
		        if ( pobTran->srBRec.lnTipAmount > 0L )
			        srAccum.inTipCount = -1;
		        srAccum.dbTotal = (double) -pobTran->srBRec.lnBaseTransactionAmount -pobTran->srBRec.lnTipAmount;
		        srAccum.dbTip = (double) -pobTran->srBRec.lnTipAmount;
		        srAccum.dbTax = (double) -pobTran->srBRec.lnTaxAmount;
		        srAccum.dbCashBack = (double) -pobTran->srBRec.lnCashBackAmount;

			if (pobTran->srBRec.lnBaseTransactionAmount == 0L)
			{
				srAccum.inSaleCount = 0;
			}
			else
			{
				srAccum.inSaleCount = -1;
			}

        #else							//meca 20041023 -- fixed from cashcard O3750 -- to correct problem in totals report -- end

        /* Put the values once for VOID bucket */
        srAccum.inCount = 1;
        if (pobTran->srBRec.lnTipAmount > 0L)
            srAccum.inTipCount = 1;
        srAccum.dbTotal = (double) pobTran->srBKey.lnTotalOfTransactionAmount;
        srAccum.dbTip = (double) pobTran->srBRec.lnTipAmount;
        srAccum.dbTax = (double) pobTran->srBRec.lnTaxAmount;
        srAccum.dbCashBack = (double) pobTran->srBRec.lnCashBackAmount;
        srAccum.dbSurCharge = (double) pobTran->srBRec.lnSChgAmount;

        if ((pinTempFn = inGetFunctionPointer(UPDATE_VOID_ACCUM_VALUES)) != NULL_PFI)
            pinTempFn(pobTran, &srAccum);

        if (inSetAccum(pobTran, inVoidType, srAccum, inTranCardType) != VS_SUCCESS)
            return(VS_ERR);

        /* And then subtract from Sale/Refund bucket */
        srAccum.inCount = -1;
        if (pobTran->srBRec.lnTipAmount > 0L)
            srAccum.inTipCount = -1;
        srAccum.dbTotal = (double) - pobTran->srBKey.lnTotalOfTransactionAmount;
        srAccum.dbTip = (double) - pobTran->srBRec.lnTipAmount;
        srAccum.dbTax = (double) - pobTran->srBRec.lnTaxAmount;
        srAccum.dbCashBack = (double) - pobTran->srBRec.lnCashBackAmount;
        srAccum.dbSurCharge = (double) - pobTran->srBRec.lnSChgAmount;

        #endif
    } else if (pobTran->fAdjust || pobTran->fTipAdjust) {
        srAccum.inCount = 0;
        srAccum.dbTip = 0.0;
        srAccum.dbTax = 0.0;
        /*
         *      Total always changes
         */
        srAccum.dbTotal = (double) (pobTran->srBKey.lnTotalOfTransactionAmount - pobTran->srBRec.lnOldTotalTransactionAmount);
        /*
         *      Tip Only changes if we are tip adjusting
         */
        if (pobTran->fTipAdjust) {
            srAccum.dbTip = (double) (pobTran->srBRec.lnTipAmount - pobTran->srBRec.lnOldTipAmount);
            if (pobTran->srBRec.lnTipAmount > 0L && pobTran->srBRec.lnOldTipAmount == 0L)
                srAccum.inTipCount = 1;
            else if (pobTran->srBRec.lnTipAmount == 0L && pobTran->srBRec.lnOldTipAmount > 0L)
                srAccum.inTipCount = -1;
        }

        /*
         *      Tax changes if we are adjusting the base and percent/processing are on.
         */
        if (pobTran->fTaxAdjust)
            srAccum.dbTax = (double) (pobTran->srBRec.lnTaxAmount - pobTran->lnOldTaxAmount);
        srAccum.dbCashBack = 0.0;    /* CashBack can not be adjusted */
        srAccum.dbSurCharge = 0.0;    /* SurCharge can not be adjusted */
    } else {
//meca 20041023 -- fixed from cashcard O3750 -- to correct the problem for totals report -- start
#ifdef CASHCARD_DEFINED
        srAccum.inCount = 1;
        if ( pobTran->srBRec.lnTipAmount > 0L )
	        srAccum.inTipCount = 1;

        srAccum.dbTotal = (double) pobTran->srBRec.lnBaseTransactionAmount;
        srAccum.dbTip = (double) pobTran->srBRec.lnTipAmount;
        srAccum.dbTax = (double) pobTran->srBRec.lnTaxAmount;
        srAccum.dbCashBack = (double) pobTran->srBRec.lnCashBackAmount;
        //srAccum.dbSurCharge = (double) pobTran->srBRec.lnSChgAmount;

	if (pobTran->srBRec.lnBaseTransactionAmount == 0L)
	{
		srAccum.inSaleCount = 0;
	}
	else
	{
		srAccum.inSaleCount = 1;
	}
#else 	//meca 20041023 -- fixed from cashcard O3750 -- to correct the problem for totals report -- end
        srAccum.inCount = 1;
        if (pobTran->srBRec.lnTipAmount > 0L)
            srAccum.inTipCount = 1;
        srAccum.dbTotal = (double) pobTran->srBKey.lnTotalOfTransactionAmount;
        srAccum.dbTip = (double) pobTran->srBRec.lnTipAmount;
        srAccum.dbTax = (double) pobTran->srBRec.lnTaxAmount;
        srAccum.dbCashBack = (double) pobTran->srBRec.lnCashBackAmount;
        srAccum.dbSurCharge = (double) pobTran->srBRec.lnSChgAmount;
#endif	//CASHCARD_DEFINED
    }

    if ((pinTempFn = inGetFunctionPointer(UPDATE_ACCUM_VALUES)) != NULL_PFI)
        pinTempFn(pobTran, &srAccum);

    return(inSetAccum(pobTran, inType, srAccum, inTranCardType));
}

/*********************************************************************************************
* @func int | inCheckBatchTotals |
* Gets the total number of transactions in the batch.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*       Transaction object.
*
* @parm long * | lnCount |
*       Number of record in the batch.
*
* @rdesc Returns the success or failure.
* @flag int | VS_SUCCESS
* @flag int | VS_ERR
* @end
**********************************************************************************************/
int inCheckBatchTotals(TRANSACTION_OBJECT* pobTran,long* lnCount) {
    ACCUM_REC srHostTotals;

    if (inGetHostTotals(pobTran, &srHostTotals) != VS_SUCCESS)
        return (VS_ERR);
    *lnCount = srHostTotals.srTotals[CREDIT_CARD].lnCount[DEBIT_TRAN] + srHostTotals.srTotals[CREDIT_CARD].lnCount[CREDIT_TRAN] + srHostTotals.srTotals[DEBIT_CARD].lnCount[DEBIT_TRAN] + srHostTotals.srTotals[DEBIT_CARD].lnCount[CREDIT_TRAN];

    return (VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inUpdateAccumFlow |
*       This routine updates the Accumulators if necessary.  It is intended to be used from the TRT.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end
**********************************************************************************************/

int inUpdateAccumFlow(TRANSACTION_OBJECT* pobTran) {
    /** /pdebug(("--inUpdateAccumFlow--"));*/



    if (!fGetDataCapture(pobTran))
        return(VS_SUCCESS);

    /* pj1 - skip inUpdateAccum if open tab */
    if (pobTran->fOTBatchOpen)
        return(VS_SUCCESS);

    /* Store the power failure recovery state */
    inPFRStateStoreAll(PFR_BEGIN_UPDATE_ACCUM, pobTran, 1, 1);


    if (inUpdateAccum(pobTran) != VS_SUCCESS) {
        vdSGErrorMessage(ACCUM_ERR_MSG);
        return(VS_ERR);
    }

    /* Store the power failure recovery state */
    inPFRStateStoreAll(PFR_UPDATE_ACCUM_COMPLETE, pobTran, 1, 1);

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inSummaryReportOperation |
*
*       Print Totals Report Operation.
*
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end

**********************************************************************************************/

int inSummaryReportOperation(TRANSACTION_OBJECT* pobTran) {
    /*    pdebug(("--inSummaryReportOperation--"));*/

    if (inGetPrinterType() == NOPRINTER && fGetEnablePrinter()) {
        vdDisplayMessageFromFile(NO_PRINTER_MSG, WARNING_MSG);
        return(VS_SUCCESS);
    }
    if (!fGetEnablePrinter())
        return(VS_SUCCESS);

    inGetReport1Template();

    return(inPrintSummaryReport(&obPrinter, pobTran));
}

/*********************************************************************************************
* @func int | inPrintSummaryReport |
*
*       Print Totals Report.
*
* @parm PRINTER_OBJECT * | pobPrinter |
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end

**********************************************************************************************/

int inPrintSummaryReport(PRINTER_OBJECT* pobPrinter,TRANSACTION_OBJECT* pobTran) {
    char szDate[DATE_SIZE + 1];
    int inStart,
    inStop,
    inNumberOfMerchants,
    inMerch = 0;
    int inHostIndex;
    int inReportTop = VS_TRUE;

    if (fChkAllHostBatches(pobTran)) {
        vdDisplayMessageFromFile(BATCH_EMPTY_MSG, WARNING_MSG);
        return(VS_SUCCESS);
    }

    inNumberOfMerchants = inSelectOneAllMID(pobTran, fGetMultiMerchPrompt());
    if (inNumberOfMerchants == inGetMITTotRecs()) {
        inStart = 1;
        inStop = inGetMITTotRecs();
    } else if (inNumberOfMerchants == 1) {
        inStart = inGetMerchantNum();
        inStop = inGetMerchantNum();
    } else {
        inStart = 1;
        inStop = 0;
    }

    for (inMerch = inStart; inMerch <= inStop; inMerch++) {
        if (inLoadMITRec(inMerch - 1) != VS_SUCCESS)
            return(VS_ERR);

        /* Get the total number of records in the batch */
        if (inGetDCBatchRecCnt(pobTran) == 0) {
            /* loop back for next merchant */
            continue;
        }

        if (fGetEnablePrinter())
            vdDisplayMessageFromFile(PRINTING_MSG, STATUS_MSG);

        if (inGGCode() == SETTLE) {
            vdGetDate(szDate, MMDDYY);
            strlcpy(pobTran->szSettDate, szDate, DATE_SIZE);
        }

        for (inHostIndex = 0; inHostIndex < MAX_HOSTS; inHostIndex++) {
            //            vdSetHostHandle(inHostIndex);

            if (inLoadDefaultHost(inHostIndex) != VS_SUCCESS)
                return (VS_ERR);

            if (inLoadDefaultCurrency(pobTran) != VS_SUCCESS)
                return (VS_ERR);

            /* Only print the report for independent host */
            if (fGetIndependentBatch()) {
                /* Print the overall totals */
                inPrintSummaryMiddle(pobPrinter, pobTran, &inReportTop, inNumberOfMerchants, inMerch); /* mb1 */
            }
        } /* host loop */
        /* Print FORM_FEED  */
        if (inPrintLines(pobPrinter, SUMMARY_FORM_FEED, SUMMARY_FORM_FEED_END, NO_BL_LINE, 0x80000000) != VS_SUCCESS)
            return(VS_ERR);
    } /* merchant loop */

    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func int | inPrintSummaryMiddle |
*
*       Browse the Acummulators and print items with totals.
*
* @parm PRINTER_OBJECT * | pobPrinter |
* @parm TRANSACTION_OBJECT * | pobTran |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end

**********************************************************************************************/


int inPrintSummaryMiddle(PRINTER_OBJECT* pobPrinter,TRANSACTION_OBJECT* pobTran,int* pinReportTop,int inNumberOfMerchants,int inWhichMerchant) {
    int inNewHost;
    CARD_TOTS_REC srGrandTots;
    int inIssuer;
    int inIssuerCnt;
    int inGrandIssuerCnt = 0;
    int inRetVal = 0;
    int inResult;
    long lnRecNum = 0;
    long lnCount;
    double dbAmount,
    dbTip,
    dbTax,
    dbSurCharge,
    dbCashBack;
    char szFileName[FILENAME_SIZE + 1];
    char szHostName[HOST_NAME_SIZE + 1];
    DB_FILE srDBFPtr;
    ACCUM_REC srAccumRec;
    ACCUM_KEY srAccumKey;
    ACCUM_SKEY srAccumSKey;
    int inKeyIdx = 0;
    FHANDLE hFHandle;
    ACCUM_SHIFT srASI;
    unsigned char ucIITTempRec[SIZE_IIT_REC + 1];
    //    IIT_REC srIITTempRec;



    memset((char *) &srGrandTots, 0x00, (SIZE_CARD_TOTS_REC)); {
        srGrandTots.inTotalCnt = 0;
        srGrandTots.dbTotalAmt = 0.0;
        srGrandTots.dbSaleAmt = 0.0;
        srGrandTots.dbTipAmt = 0.0;
        srGrandTots.dbTaxAmt = 0.0;
        srGrandTots.dbSurCharge = 0.0;
        srGrandTots.dbCashBack = 0.0;
    }

    vdGetAccumFName(szFileName);

    if (inOpenAccum(&srDBFPtr, szFileName) != VS_SUCCESS) {

        vdSGErrorMessage(BATCH_ERR_MSG);
        return(VS_ERR);
    }

    vdSetSummaryMiddleCondition();

    /*  Read ASI File to use for determining if issuer accumulator has been updated */


    vdGetASIFName(szFileName);
    if ((hFHandle = open(szFileName, O_RDWR)) < 0) {
        if ((hFHandle = open(szFileName, O_CREAT | O_RDWR)) < 0)
            return(VS_ERR);

        memset((char *) &srASI, 0x00, SIZE_ACCUM_SHIFT);
    } else
        inResult = read(hFHandle, (char *) &srASI, SIZE_ACCUM_SHIFT);

    close(hFHandle);

    srAccumSKey.compare_func = inAccumCompFn;
    inNewHost = VS_TRUE;
    inIssuerCnt = 0;

    for (inIssuer = 0; inIssuer < TOTAL_ISSUERS; inIssuer++) {
        if ((inLoadIITRecFromStruct(inIssuer, ucIITTempRec)) == VS_ERR) {
            inCloseAccum(&srDBFPtr);
            vdSGErrorMessage(IIT_ERR_MSG21);
            return(VS_ERR);
        }

        if (srASI.srIssuer.fActiveAccum[inGetIssuerNumberFromStruct(ucIITTempRec)] == '\0')
            continue;

        strlcpy(srRcpt.unFrm.srSummary.srMid.szCType, szGetIssuerAbbrevFromStruct(ucIITTempRec), SML_CLABEL_SIZE);

        srAccumKey.inIssuerNumber = inGetIssuerNumberFromStruct(ucIITTempRec);
        srAccumSKey.accumKey.inIssuerNumber = inGetIssuerNumberFromStruct(ucIITTempRec);
        /* If record does not exist then go to next issuer */
        inRetVal = inKeyReadAccum(&srDBFPtr, &srAccumRec, &srAccumKey, &srAccumSKey, &lnRecNum);
        if (inRetVal == VS_SUCCESS) {
            if (inNewHost) {
                if (*pinReportTop == VS_TRUE) {
                    vdMakeReportHeader(pobTran);
                    if ((inGetMITTotRecs() == 1 || inNumberOfMerchants == 1) || (inNumberOfMerchants == inGetMITTotRecs() && inWhichMerchant == 1))
                        inPrintReportHeader(pobTran, pobPrinter);
                    else {
                        if (inPrintLines(pobPrinter, REPORT_HEADER_START, REPORT_HEADER_END, NO_BL_LINE, lnHeaderCondition) != VS_SUCCESS) {
                            inCloseAccum(&srDBFPtr);
                            return(VS_ERR);
                        }
                    }
                }

                inNewHost = VS_FALSE;
                /* Header condition should not print report title except at top of report */
                vdSetSummaryHeaderCondition(*pinReportTop, VS_FALSE);
                *pinReportTop = VS_FALSE;

                strlcpy(srRcpt.szMerchantName, szGetMerchantText(), MESSAGE_SIZE);
                strcpy(szHostName, szGetHostName());
                strlcpy(srRcpt.szHostName, szHostName, (int)sizeof(srRcpt.szHostName));
                if (inPrintLines(pobPrinter, SUMMARY_TOP_START, SUMMARY_TOP_END, NO_BL_LINE, lnHeaderCondition) != VS_SUCCESS) {
                    inCloseAccum(&srDBFPtr);
                    return(VS_ERR);
                }
            }
            /*  Use totals from record */
            lnCount = srAccumRec.srTotals[CREDIT_CARD].lnCount[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].lnCount[SALE_TRAN] + srAccumRec.srTotals[CREDIT_CARD].lnCount[REFUND_TRAN] + srAccumRec.srTotals[DEBIT_CARD].lnCount[REFUND_TRAN];

            dbAmount = srAccumRec.srTotals[CREDIT_CARD].dbAmount[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].dbAmount[SALE_TRAN] - srAccumRec.srTotals[CREDIT_CARD].dbAmount[REFUND_TRAN] - srAccumRec.srTotals[DEBIT_CARD].dbAmount[REFUND_TRAN];

            dbTip = srAccumRec.srTotals[CREDIT_CARD].dbTip[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].dbTip[SALE_TRAN] - srAccumRec.srTotals[CREDIT_CARD].dbTip[REFUND_TRAN] - srAccumRec.srTotals[DEBIT_CARD].dbTip[REFUND_TRAN];

            dbTax = srAccumRec.srTotals[CREDIT_CARD].dbTax[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].dbTax[SALE_TRAN] - srAccumRec.srTotals[CREDIT_CARD].dbTax[REFUND_TRAN] - srAccumRec.srTotals[DEBIT_CARD].dbTax[REFUND_TRAN];

            dbSurCharge = srAccumRec.srTotals[CREDIT_CARD].dbSurCharge[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].dbSurCharge[SALE_TRAN] - srAccumRec.srTotals[CREDIT_CARD].dbSurCharge[REFUND_TRAN] - srAccumRec.srTotals[DEBIT_CARD].dbSurCharge[REFUND_TRAN];

            dbCashBack = srAccumRec.srTotals[CREDIT_CARD].dbCashBack[SALE_TRAN] + srAccumRec.srTotals[DEBIT_CARD].dbCashBack[SALE_TRAN] - srAccumRec.srTotals[CREDIT_CARD].dbCashBack[REFUND_TRAN] - srAccumRec.srTotals[DEBIT_CARD].dbCashBack[REFUND_TRAN];

            /* Set print line */
            sprintf(srRcpt.unFrm.srSummary.srMid.szCreditCount, SUBSTITUTE_LD, lnCount);
            /* Total Amount */

            /* sprintf(srRcpt.unFrm.srSummary.srMid.szCreditTotal, SUBSTITUTE_LD, lnAmount); */
            /* will put dollar sign in front */
            /* vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szCreditTotal);  */

            vdDb2Str(dbAmount, srRcpt.unFrm.srSummary.srMid.szCreditTotal);
            vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szCreditTotal, VS_FALSE);
            vdTrimLeadSpaces(srRcpt.unFrm.srSummary.srMid.szCreditTotal);

            /* Sale Amount (Base Amount)*/


            /*  sprintf(srRcpt.unFrm.srSummary.srMid.szDebitTotal, SUBSTITUTE_LD,
                               (lnAmount - lnTip - lnTax - lnSurCharge - lnCashBack));*/

            vdDb2Str((dbAmount - dbTip - dbTax - dbSurCharge - dbCashBack), srRcpt.unFrm.srSummary.srMid.szDebitTotal);
            vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szDebitTotal, VS_FALSE);
            vdTrimLeadSpaces(srRcpt.unFrm.srSummary.srMid.szDebitTotal);

            /*Tip Amount */
            /*sprintf(srRcpt.unFrm.srSummary.srMid.szAdjustTotal, SUBSTITUTE_LD, lnTip);*/

            vdDb2Str(dbTip, srRcpt.unFrm.srSummary.srMid.szAdjustTotal);
            vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szAdjustTotal, VS_FALSE);
            vdTrimLeadSpaces(srRcpt.unFrm.srSummary.srMid.szAdjustTotal);

            /*CashBack Amount */
            /*sprintf(srRcpt.unFrm.srSummary.srMid.szCashBackTotal, SUBSTITUTE_LD, lnCashBack);*/

            vdDb2Str(dbCashBack, srRcpt.unFrm.srSummary.srMid.szCashBackTotal);
            vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szCashBackTotal, VS_FALSE);
            vdTrimLeadSpaces(srRcpt.unFrm.srSummary.srMid.szCashBackTotal);

            if (inPrintLines(pobPrinter, SUMMARY_MIDDLE_START, SUMMARY_MIDDLE_END, NO_BL_LINE, lnMiddleCondition) != VS_SUCCESS) {
                inCloseAccum(&srDBFPtr);
                return(VS_ERR);
            }

            if (act_kbd_pending_test(KEY_CANCEL)) {
                inCloseAccum(&srDBFPtr);
                return(VS_ESCAPE);
            }

            /* Accumulate totals */


            srGrandTots.inTotalCnt += (int) lnCount;
            srGrandTots.dbTotalAmt += dbAmount;
            srGrandTots.dbSaleAmt += (dbAmount - dbTip - dbTax - dbSurCharge - dbCashBack);
            srGrandTots.dbTipAmt += dbTip;
            srGrandTots.dbTaxAmt += dbTax;
            srGrandTots.dbSurCharge += dbSurCharge;
            srGrandTots.dbCashBack += dbCashBack;

            inIssuerCnt++;
            if (inIssuerCnt > inGrandIssuerCnt)
                inGrandIssuerCnt = inIssuerCnt;
        }
    }
    inCloseAccum(&srDBFPtr);

    /* Print Grand Totals for each host */
    if (inGrandIssuerCnt > 0) {
        /* Set print line */
        sprintf(srRcpt.unFrm.srSummary.srMid.szCreditCount, SUBSTITUTE_D, srGrandTots.inTotalCnt);
        /* Total Amount */

        /*sprintf(srRcpt.unFrm.srSummary.srMid.szCreditTotal, SUBSTITUTE_LD,
            srGrandTots.lnTotalAmt);*/

        vdDb2Str(srGrandTots.dbTotalAmt, srRcpt.unFrm.srSummary.srMid.szCreditTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szCreditTotal, VS_TRUE);

        /* Sale Amount */

        /*sprintf(srRcpt.unFrm.srSummary.srMid.szDebitTotal, SUBSTITUTE_LD,
            srGrandTots.lnSaleAmt);*/

        vdDb2Str(srGrandTots.dbSaleAmt, srRcpt.unFrm.srSummary.srMid.szDebitTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szDebitTotal, VS_TRUE);

        /*Tip Amount */
        /*sprintf(srRcpt.unFrm.srSummary.srMid.szAdjustTotal, SUBSTITUTE_LD,
            srGrandTots.lnTipAmt);*/
        vdDb2Str(srGrandTots.dbTipAmt, srRcpt.unFrm.srSummary.srMid.szAdjustTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szAdjustTotal, VS_TRUE);

        /*Tax Amount */
        /*sprintf(srRcpt.unFrm.srSummary.srMid.szTaxTotal, SUBSTITUTE_LD,
            srGrandTots.lnTaxAmt);*/
        vdDb2Str(srGrandTots.dbTaxAmt, srRcpt.unFrm.srSummary.srMid.szTaxTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szTaxTotal, VS_TRUE);
        /*Surcharge Amount */
        /*sprintf(srRcpt.unFrm.srSummary.srMid.szSurchrgeTotal, SUBSTITUTE_LD,
            srGrandTots.lnSurCharge);*/
        vdDb2Str(srGrandTots.dbSurCharge, srRcpt.unFrm.srSummary.srMid.szSurchrgeTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szSurchrgeTotal, VS_TRUE);

        /*CashBack Amount */
        /*sprintf(srRcpt.unFrm.srSummary.srMid.szCashBackTotal, SUBSTITUTE_LD,
            srGrandTots.lnCashBack);*/
        vdDb2Str(srGrandTots.dbCashBack, srRcpt.unFrm.srSummary.srMid.szCashBackTotal);
        vdFormatAmount(srRcpt.unFrm.srSummary.srMid.szCashBackTotal, VS_TRUE);
        /* Send VS_TRUE so FORM_FEED will print */
        vdSetSummaryBottomCondition(pobTran, VS_TRUE, &srGrandTots);
        if (inPrintLines(pobPrinter, SUMMARY_BOTTOM_START, SUMMARY_BOTTOM_END, NO_BL_LINE, lnBottomCondition) != VS_SUCCESS)
            return(VS_ERR);
    }
    return(VS_SUCCESS);
}

/*********************************************************************************************
* @func void | vdSetSummaryHeaderCondition |
*
*       Set conditions for Totals Report.
*
* @parm int  | inReportTop |
* @parm int  | inGrandTotals |
*
* @rdesc return values.
* @flag int    |  VS_SUCCESS
* @flag int    |  VS_ERR
* @end

**********************************************************************************************/

void vdSetSummaryHeaderCondition(int inReportTop,int inGrandTotals) {
    if (inGetPrinterType() == NOPRINTER || !fGetEnablePrinter())
        return;

    lnHeaderCondition = formater_set_flags(inReportTop, (inReportTop && fGetDemoMode() == VS_TRUE), (inGetMITTotRecs() > 1),
                        0,

                        0,
                        0,
                        0,
                        0,

                        0,
                        0,
                        0,
                        0,

                        0,
                        0,
                        0,
                        0,

                        (inGetTipProcessing() == TIP_OFF && !(fGetCashBack())),
                        (inGetTipProcessing() > TIP_OFF && !(fGetCashBack())),
                        (inGetTipProcessing() == TIP_OFF && fGetCashBack()),
                        (inGetTipProcessing() > TIP_OFF && fGetCashBack()),

                        0,
                        0,
                        0,
                        0,

                        0,
                        0,
                        0,
                        0,

                        0,
                        0,
                        0,
                        0, -1);
}

/*********************************************************************************************
* @func void | vdSetSummaryMiddleCondition |
*
*       Set conditions for Totals Report.
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdSetSummaryMiddleCondition() {
    lnMiddleCondition = formater_set_flags(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (inGetTipProcessing() > TIP_OFF),
                (inGetTipProcessing() > TIP_OFF && !(fGetCashBack())),
                (inGetTipProcessing() == TIP_OFF && fGetCashBack()),
                (inGetTipProcessing() > TIP_OFF && fGetCashBack()),

                0,
                0,
                0,
                0,

                0,
                0,
                0,
                0,

                0,
                0,
                0,
                0, -1);
}

/*********************************************************************************************
* @func void | vdSetSummaryBottomCondition |
*
*       Set conditions for Totals Report.
*
* @parm TRANSACTION_OBJECT * | pobTran |
* @parm int  | inFormFeed |
* @parm CARD_TOTS_REC * | srTots |
*
* @rdesc VOID
* @end
**********************************************************************************************/

void vdSetSummaryBottomCondition(TRANSACTION_OBJECT* pobTran,int inFormFeed,CARD_TOTS_REC* srTots) {
    lnBottomCondition = formater_set_flags((inFormFeed), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, (fGetTaxProc() || srTots->dbTaxAmt > 0),
                0,
                0,
                0,

                0,
                0,
                0,
                0,

                0,
                0,
                0,
                0,

                (inGetTipProcessing() > TIP_OFF),
                (fGetCashBack()),
                inGetSurCharge(),
                0, -1);
}

/*-------------------------------------------------------------------------
    Function :  inBatchTotalsOperation()
    Description : Displays the cuurrent batch totals for a particular host
    Parameters :
    Returns : VS_SUCCESS, VS_ERR
    Globals :
    Notes :
    Modification History :
      #     Date      Who                     Description
    ----- -------- ---------- ---------------------------------------------
      1   02/22/97 Jim_B4     Created
      2   12/09/97 Page_K1    Remove use of ALL_TOTALS.
--------------------------------------------------------------------------*/

int inBatchTotalsOperation(TRANSACTION_OBJECT* pobTran) {
    double dbSalesTotal,
    dbRefundsTotal;
    char szSalesAmt[AMT_SIZE + 1];
    char szRefundsAmt[AMT_SIZE + 1];
    char szTotalAmt[AMT_SIZE + 1];
    ACCUM_REC srHostTotals;

    /** /pdebug(("--inBatchTotalsOperation--"));*/

    if (inGetHostNum(pobTran) == VS_SUCCESS)   /* select host */ {
        if (inGetHostTotals(pobTran, &srHostTotals) != VS_SUCCESS)
            return (VS_ERR);

        if (inGetHostTranCnt(pobTran) == 0) {
            vdSGErrorMessage(BATCH_EMPTY_MSG);
            return (VS_ERR);
        }

        dbSalesTotal = srHostTotals.srTotals[CREDIT_CARD].dbAmount[DEBIT_TRAN] + srHostTotals.srTotals[DEBIT_CARD].dbAmount[DEBIT_TRAN];
        dbRefundsTotal = srHostTotals.srTotals[CREDIT_CARD].dbAmount[CREDIT_TRAN] + srHostTotals.srTotals[DEBIT_CARD].dbAmount[CREDIT_TRAN];
        szSalesAmt[0] = '\0';
        vdDb2Str(dbSalesTotal, szSalesAmt);

        //          sprintf(szSalesAmt, SUBSTITUTE_LD, lnSalesTotal);

        szRefundsAmt[0] = '\0';
        vdDb2Str(dbRefundsTotal, szRefundsAmt);

        //            sprintf(szRefundsAmt, SUBSTITUTE_LD, lnRefundsTotal);

        szTotalAmt[0] = '\0';
        vdDb2Str((dbSalesTotal - dbRefundsTotal), szTotalAmt);

        //sprintf(szTotalAmt, SUBSTITUTE_LD, lnSalesTotal - lnRefundsTotal);

        vdDispFormattedAmt(szSalesAmt, SALES_AMT_MSG, obDisp.inStatusLine - 2);
        vdDispFormattedAmt(szRefundsAmt, REFUNDS_AMT_MSG, obDisp.inStatusLine - 1);
        vdDispFormattedAmt(szTotalAmt, TOTALAMT_MSG9, obDisp.inStatusLine);

        inWaitKey(inGetIdleTimeOut());
    } else
        return (VS_ERR);

    return(VS_SUCCESS);
}


int inDefaultUpdateAccumValues(TRANSACTION_OBJECT* pobTran,ACCUM_VALUES* psrAccum) {
    return(VS_SUCCESS);
}

int inDefaultVoidUpdateAccumValues(TRANSACTION_OBJECT* pobTran,ACCUM_VALUES* psrAccum) {
    return(VS_SUCCESS);
}

void vdDb2Str(double dbValue,char* pchString) {
    sprintf(pchString, "%15.2f", dbValue);
    pchString[strlen(pchString) - 3] = NULL_CH;
    vdTrimLeadSpaces(pchString);
}


int ACCUM_CODE_CHECK(char* a,char* b,short * c,char* d,unsigned char* e) {
    GET_VER(a, b, c, d, e);
    return 1;
}

#undef ACCUM_C

#endif
